package com.ufgov.pdf.entity;

import java.beans.BeanInfo;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Method;
import java.math.BigDecimal;
import java.util.HashMap;
import java.util.Map;

import com.ufgov.pdf.util.StringUtil;

/**
 * pdf bean基类. 将需要转换为Map的bean继承自此抽象类 如果所需要的类型在toMap方法中不存在,可以添加;
 * 如果基类的toMap方法实在不能满足您的需求,您可以重写此方法
 * 
 * @author lihh
 *
 */
public abstract class BaseMapBean {
	/**
	 * 转化为Map
	 * @param digit 
	 * 			BigDecimal的转换精度
	 * @author zhangdand at 2018年4月11日下午1:54:50
	 */
	public Map<String,Object> toMap(Integer digit){
		if (digit == null || digit < 0) {
			digit = 2;
		}
		Map<String, Object> map = new HashMap<String, Object>();
		try {
			// 内省是 Java 语言对 Bean 类属性、事件的一种缺省处理方法。例如类 PersonBean中有属性 name,
			// 那我们可以通过
			// getName,setName 来得到其值或者设置新的值。通过 getName/setName 来访问 name
			// 属性，这就是默认的规则。 Java
			// 中提供了一套 API 用来访问某个属性的 getter/setter 方法，通过这些 API
			// 可以使你不需要了解这个规则（但你最好还是要搞清楚），这些
			// API 存放于包 java.beans 中。注意：
			// PersonBean中属性mN的getter/setter方法必须满足javaBean命名规范，即getmN，不能写作getMN，否则转换失败。
			BeanInfo beanInfo = Introspector.getBeanInfo(this.getClass());
			PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
			for (PropertyDescriptor property : propertyDescriptors) {
				String key = property.getName();
				// 过滤class属性
				if (!key.equals("class")) {
					// 得到property对应的getter方法
					Method getter = property.getReadMethod();
					Object value = getter.invoke(this);
					if (value != null) {
						if (value instanceof BigDecimal) {
							// 这个地方是不是要把精度做成可选?
							value = StringUtil.numberFormat((BigDecimal) value, digit);
						} else {
							System.out.println(value.getClass().toString());
						}
					}
					map.put(key, value);
				}

			}
		} catch (Exception e) {
			e.printStackTrace();
			System.out.println("transBean2Map Error " + e);
			return null;
		}

		return map;
	}
	/**
	 * 转换为Map
	 * @param proDigit
	 * 			BigDecimal的转换精度，按实体属性设置
	 * @author zhangdand at 2018年4月16日上午11:24:47
	 */
	public Map<String,Object> toMap(Map<String,Integer> proDigit){
		Map<String, Object> map = new HashMap<String, Object>();
		try {
			// 内省是 Java 语言对 Bean 类属性、事件的一种缺省处理方法。例如类 PersonBean中有属性 name,
			// 那我们可以通过
			// getName,setName 来得到其值或者设置新的值。通过 getName/setName 来访问 name
			// 属性，这就是默认的规则。 Java
			// 中提供了一套 API 用来访问某个属性的 getter/setter 方法，通过这些 API
			// 可以使你不需要了解这个规则（但你最好还是要搞清楚），这些
			// API 存放于包 java.beans 中。注意：
			// PersonBean中属性mN的getter/setter方法必须满足javaBean命名规范，即getmN，不能写作getMN，否则转换失败。
			BeanInfo beanInfo = Introspector.getBeanInfo(this.getClass());
			PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
			for (PropertyDescriptor property : propertyDescriptors) {
				String key = property.getName();
				// 过滤class属性
				if (!key.equals("class")) {
					// 得到property对应的getter方法
					Method getter = property.getReadMethod();
					Object value = getter.invoke(this);
					if (value != null) {
						if (value instanceof BigDecimal) {
							// 这个地方是不是要把精度做成可选?
							if(proDigit.containsKey(key)){
								value = StringUtil.numberFormat((BigDecimal) value, proDigit.get(key));
							}else{//默认保留两位小数
								value = StringUtil.numberFormat((BigDecimal) value, 2);
							}
						} else {
							System.out.println(value.getClass().toString());
						}
					}
					map.put(key, value);
				}

			}
		} catch (Exception e) {
			e.printStackTrace();
			System.out.println("transBean2Map Error " + e);
			return null;
		}

		return map;
	}
}
